package org.jdemo.orm.mybatis.support;

import org.apache.commons.beanutils.PropertyUtils;
import org.jdemo.orm.mybatis.support.mybatis.MybatisContext;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Updater
 *
 * @author longlin(longlin@cyou-inc.com)
 * @date 202014/4/15
 * @since V1.0
 */
public class Updater implements Serializable {
    private static final long serialVersionUID = -1648133608769657596L;

    /**
     * 等于操作
     */
    public static final String OPT_EQ = "eq";

    private Map<String, FieldUpdater> fields;

    public static Updater update(String key, Object value) {
        Updater updater = new Updater();
        updater.addField(key, OPT_EQ, value);
        return updater;
    }

    public Updater() {
        this.fields = new HashMap<String, FieldUpdater>();
    }

    public Updater setFields(Map<String, FieldUpdater> fields) {
        this.fields = fields;
        return this;
    }

    public Updater addField(String key, Object value) {
        this.fields.put(key, new FieldUpdater(key, OPT_EQ, value));
        return this;
    }

    public Updater addField(String key, String operator, Object value) {
        this.fields.put(key, new FieldUpdater(key, operator, value));
        return this;
    }

    public Map<String, FieldUpdater> getFields() {
        return fields;
    }

    public static <T> Updater fromEntity(T entity, List<String> includeProperties, boolean withNullField, String idProperty, String[] properties) {
        Updater updater = new Updater();
        try {
            for (String property : properties) {
                if (property.equals(idProperty)) {
                    continue;
                }
                Object propertyVal = PropertyUtils.getProperty(entity, property);
                if (includeProperties != null && includeProperties.contains(property)) {
                    if (withNullField || propertyVal != null) {
                        updater.addField(property, propertyVal);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return updater;
    }

    public Map<String, Object> toMap() {
        Map<String, String> opts = new HashMap<String, String>();
        opts.put("OPT_EQ", OPT_EQ);

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("opts", opts);
        map.put("fields", fields);
        return map;
    }

    public Map<String, Object> toMap(String tableName) {
        Map<String, Object> map = this.toMap();
        if (tableName != null && tableName.length() > 0) {
            map.put(MybatisContext.TABLE_NAME, tableName);
        }
        return map;
    }

    public Map<String, Object> toMap(String tableName, Parameter param) {
        Map<String, Object> map = this.toMap(tableName);
        map.putAll(param.toMap());
        return map;
    }
}
